<?php
// +----------------------------------------------------------------------
// | 功能:自提模块
// +----------------------------------------------------------------------
// | 作者:崔骏
// +----------------------------------------------------------------------
// | 时间:2025.03.11
// +----------------------------------------------------------------------

namespace app\keeper\controller;

use app\common\lib\Str;
use app\common\model\mysql\In;
use app\common\model\mysql\InProduct;
use app\common\model\mysql\Order;
use app\common\business\Order as OrderBus;
use app\common\model\mysql\OrderBackBucket;
use app\common\model\mysql\OrderProductNormal;
use app\common\model\mysql\OrderProductWater;
use app\common\model\mysql\OrderTakeselfBackBucket;
use app\common\model\mysql\Out;
use app\common\model\mysql\OutProduct;
use app\common\model\mysql\Product;
use app\common\model\mysql\WarehouseSpaceProduct;
use think\facade\Db;

class Since extends AuthBase
{
    /**
     * 自提产品列表
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function sincePage(){
        $productConditions = [
            ['company_id', '=', $this->companyId],
            ['shop_id', '=', $this->shopId],
            ['typeenum', '=', 4],
            ['isdel', '=', 0],
        ];
        $productData = (new Product())->getNormalProduct($productConditions, 'product_id,product_name');
        foreach ($productData as &$product) {
            $product['product_name'] .= "(好桶)";
        }
        $todayStart = date('Y-m-d 00:00:00');
        $todayEnd = date('Y-m-d 23:59:59');
        $orderConditions = [
            ['shop_id', '=', $this->shopId],
            ['ordertypeenum', '=', 2],
            ['create_time', 'between', [$todayStart, $todayEnd]],
        ];
        $orderRepository = new Order();
        $maxGoodsCode = $orderRepository->getNormalOrderMax($orderConditions, 'goods_code');
        $goodsCode = $maxGoodsCode ?? 1; // 使用空合并运算符
        $goodsCode++;
        $responseData = [
            'productData' => $productData,
            'collectionCode' => $goodsCode,
        ];
        return show(config("status.success"),"自提页面",$responseData);
    }

    /**
     * 自提订单提交
     * @return \think\response\Json
     */
    public function sinceLift(){
        $bucketData = $this->request->param('bucketData');
        if ($bucketData) {
            foreach ($bucketData as $value) {
                if (!array_key_exists('product_id', $value) ||
                    !array_key_exists('count', $value) ||
                    !array_key_exists('product_name', $value)) {
                    return show(config("status.error"), "商品数据传输有误");
                }
            }
        }
        $todayStart = date('Y-m-d 00:00:00');
        $todayEnd = date('Y-m-d 23:59:59');
        $orderConditions = [
            ['shop_id', '=', $this->shopId],
            ['ordertypeenum', '=', 2],
            ['create_time', 'between', [$todayStart, $todayEnd]],
        ];
        $orderRepository = new Order();
        $maxGoodsCode = $orderRepository->getNormalOrderMax($orderConditions, 'goods_code');
        $goodsCode = $maxGoodsCode ?? 1; // 使用空合并运算符
        $goodsCode++;
        try {
            Db::startTrans(); // 开始事务
            $orderAddData['company_id'] = $this->companyId;
            $orderAddData['shop_id'] = $this->shopId;
            $orderAddData['ordertypeenum'] = 2;
            $orderAddData['typeitemenum'] = 32;
            $orderAddData['worker_id_product_in'] = $this->workerId;
            $orderAddData['worker_name_product_in'] = $this->workerName;
            $orderAddData['stateenum'] = 1;
            $orderAddData['sourceenum'] = 4;
            $orderAddData['create_time'] = date("Y-m-d H:i:s",time());
            $orderAddData['order_sn'] = (new Str())->makeOrderNo($this->shopId,1);
            $orderAddData['goods_code'] = $goodsCode;
            $orderAddRes = (new Order())->addOrderData($orderAddData);
            if(empty($orderAddRes)){
                return show(config("status.error"),"提交订单失败");
            }
            if($bucketData){
                foreach ($bucketData as $key => $value) {
                    $productBucketData = (new Product())->getProductFind([['product_id','=',$value['product_id']]],'parentid,typeenum,product_name,price_unit');
                    $order_child[$key]['order_id'] = $orderAddRes;
                    $order_child[$key]['product_id'] = $value['product_id'];
                    $order_child[$key]['product_name'] = $productBucketData['product_name'];
                    $order_child[$key]['product_id_water'] = $productBucketData['parentid'];
                    $order_child[$key]['tcount'] = $value['count'];
                    $order_child[$key]['bucket_value'] = $productBucketData['price_unit'];
                    $order_child[$key]['back_buckettypeenum'] = 1;
                    $order_child[$key]['producttypeenum'] = $productBucketData['typeenum'];
                    $order_child[$key]['worker_id'] = $this->workerId;
                    $order_child[$key]['worker_name'] = $this->workerName;
                    $order_child[$key]['adddate'] = date("Y-m-d H:i:s",time());
                }
                (new OrderTakeselfBackBucket())->addAllOrderTakeselfBackBucket($order_child);
            }
            // 提交事务
            Db::commit();
            return show(config("status.success"),"提交成功",['success'=>200]);
        }catch (\Exception $e){
            // 回滚事务
            Db::rollback();
            return show(config("status.error"),$e->getMessage());
        }
    }

    /**
     * 自提订单列表
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function sinceOrderList(){
        $page = $this->request->param('pageNum', 1);//当前页
        $limit = $this->request->param('pageSize', 10);//每页显示条数
        if(empty($page) || empty($limit)){
            return show(config("status.error"),"缺少分页参数");
        }
        $where = [
            ['company_id','=',$this->companyId],
            ['shop_id','=',$this->shopId],
            ['ordertypeenum','=',2],
            ['isdel','=','0']
        ];
        $field = "order_id,order_sn,goods_code,create_time,outdate,backdate,cashierdate,takestateenum,iscancel";
        $orderList = (new OrderBus())->getNormalOrderList($where,$limit,$page,$field);
        foreach ($orderList['data'] as $key=>$value){
            $orderList['data'][$key]['outdate'] = $value['outdate'] ?? "";
            $orderList['data'][$key]['backdate'] = $value['backdate'] ?? "";
            $orderList['data'][$key]['cashierdate'] = $value['cashierdate'] ?? "";
            $waterSellcount = (new OrderProductWater())->getOrderProductWaterSum([['order_id','=',$value['order_id']]]);
            $productSellcount = (new OrderProductNormal())->getOrderProductNormalSum([['order_id','=',$value['order_id']]]);
            $orderList['data'][$key]['sellcount'] = $waterSellcount+$productSellcount;
            $waterData = (new OrderProductWater())->getNormalOrderProductWater([['order_id','=',$value['order_id']]],'product_name,sellcount');
            $productData = (new OrderProductNormal())->getNormalOrderProductNormal([['order_id','=',$value['order_id']]],'product_name,sellcount');
            $orderList['data'][$key]['goodsData'] = array_merge($waterData,$productData);
        }
        return show(config("status.success"),"自提订单列表",$orderList['data']);
    }

    /**
     * 自提订单详情
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function sinceOrderDetails(){
        $order_id = $this->request->param('order_id');
        if(empty($order_id)){
            return show(config("status.error"),"缺少参数订单id");
        }
        $orderData = (new Order())->getOrderFind([['order_id','=',$order_id]],'goods_code');
        $outWhere = [
            ['modelid','=',$order_id],
            ['outtypeenum','=',32],
            ['modeltypeenum','=',6]
        ];
        $outData = (new Out())->getOutFind($outWhere,'id');
        $field = "order_product_water_id,product_id,product_name,sellcount,selltypeenum";
        $waterData = (new OrderProductWater())->getNormalOrderProductWater([['order_id','=',$order_id]],$field);
        foreach ($waterData as $key=>$value){
            if($outData){
                $outProductWhere = [
                    ['a.out_id','=',$outData['id']],
                    ['a.product_id','=',$value['product_id']]
                ];
                $outProductData = (new OutProduct())->getNormalOutProductFind($outProductWhere,'a.warehouse_id,a.warehouse_space_id,b.warehouse_name,c.warehouse_space_name');
                $waterData[$key]['warehouse_id'] = $outProductData['warehouse_id'];
                $waterData[$key]['warehouse_space_id'] = $outProductData['warehouse_space_id'];
                $waterData[$key]['warehouse_name'] = $outProductData['warehouse_name'];
                $waterData[$key]['warehouse_space_name'] = $outProductData['warehouse_space_name'];
            }else{
                $warehouseSpaceProductData = (new WarehouseSpaceProduct())->getNormalWarehouseSpaceProductFind([['a.product_id','=',$value['product_id']],['a.isdel','=','0']],'b.warehouse_name,c.warehouse_space_name,a.warehouse_id,a.warehouse_space_id');
                $waterData[$key]['warehouse_id'] = $warehouseSpaceProductData['warehouse_id'];
                $waterData[$key]['warehouse_space_id'] = $warehouseSpaceProductData['warehouse_space_id'];
                $waterData[$key]['warehouse_name'] = $warehouseSpaceProductData['warehouse_name'];
                $waterData[$key]['warehouse_space_name'] = $warehouseSpaceProductData['warehouse_space_name'];
            }
        }
        $field = "order_product_normal_id as order_product_water_id,product_id,product_name,sellcount,selltypeenum";
        $productData = (new OrderProductNormal())->getNormalOrderProductNormal([['order_id','=',$order_id]],$field);
        foreach ($productData as $key=>$value){
            if($outData){
                $outProductWhere = [
                    ['a.out_id','=',$outData['id']],
                    ['a.product_id','=',$value['product_id']]
                ];
                $outProductData = (new OutProduct())->getNormalOutProductFind($outProductWhere,'b.warehouse_name,c.warehouse_space_name,a.warehouse_id,a.warehouse_space_id');
                $productData[$key]['warehouse_id'] = $outProductData['warehouse_id'];
                $productData[$key]['warehouse_space_id'] = $outProductData['warehouse_space_id'];
                $productData[$key]['warehouse_name'] = $outProductData['warehouse_name'];
                $productData[$key]['warehouse_space_name'] = $outProductData['warehouse_space_name'];
            }else{
                $warehouseSpaceProductData = (new WarehouseSpaceProduct())->getNormalWarehouseSpaceProductFind([['a.product_id','=',$value['product_id']],['a.isdel','=','0']],'b.warehouse_name,c.warehouse_space_name,a.warehouse_id,a.warehouse_space_id');
                $productData[$key]['warehouse_id'] = $warehouseSpaceProductData['warehouse_id'];
                $productData[$key]['warehouse_space_id'] = $warehouseSpaceProductData['warehouse_space_id'];
                $productData[$key]['warehouse_name'] = $warehouseSpaceProductData['warehouse_name'];
                $productData[$key]['warehouse_space_name'] = $warehouseSpaceProductData['warehouse_space_name'];
            }
        }
        $bucketData = (new OrderTakeselfBackBucket())->getNormalOrderTakeselfBackBucket([['order_id','=',$order_id]],'id as order_back_bucket_id,product_id,product_name,tcount as back_count,back_buckettypeenum as buckettypeenum,producttypeenum');
        foreach ($bucketData as $key => $value) {
            if($value['producttypeenum'] == 4){
                $bucketData[$key]['product_name'] = $value['product_name']."(好桶)";
            }elseif ($value['producttypeenum'] == 8) {
                $bucketData[$key]['product_name'] = $value['product_name']."(坏桶)";
            }elseif ($value['producttypeenum'] == 16) {
                $bucketData[$key]['product_name'] = $value['product_name']."(杂桶)";
            }
        }

        $inWhere = [
            ['modelid','=',$order_id],
            ['intypeenum','=',32],
            ['modeltypeenum','=',6]
        ];
        $inData = (new In())->getInFind($inWhere,'id');
        foreach ($bucketData as $key=>$value){
            if($inData){
                $inProductWhere = [
                    ['a.in_id','=',$inData['id']],
                    ['a.product_id','=',$value['product_id']]
                ];
                $inProductData = (new InProduct())->getNormalInProductFind($inProductWhere,'b.warehouse_name,c.warehouse_space_name,a.warehouse_id,a.warehouse_space_id');
                $bucketData[$key]['warehouse_id'] = $inProductData['warehouse_id'];
                $bucketData[$key]['warehouse_space_id'] = $inProductData['warehouse_space_id'];
                $bucketData[$key]['warehouse_name'] = $inProductData['warehouse_name'];
                $bucketData[$key]['warehouse_space_name'] = $inProductData['warehouse_space_name'];
            }else{
                $warehouseSpaceProductData = (new WarehouseSpaceProduct())->getNormalWarehouseSpaceProductFind([['a.product_id','=',$value['product_id']],['a.isdel','=','0']],'b.warehouse_name,c.warehouse_space_name,a.warehouse_id,a.warehouse_space_id');
                $bucketData[$key]['warehouse_id'] = $warehouseSpaceProductData['warehouse_id'];
                $bucketData[$key]['warehouse_space_id'] = $warehouseSpaceProductData['warehouse_space_id'];
                $bucketData[$key]['warehouse_name'] = $warehouseSpaceProductData['warehouse_name'];
                $bucketData[$key]['warehouse_space_name'] = $warehouseSpaceProductData['warehouse_space_name'];
            }
        }

        $backBucketData = (new OrderBackBucket())->getNormalBackBucket([['order_id','=',$order_id],['back_buckettypeenum','=',128]],'product_id,product_name,tcount');
        $backBucketDatas = [];
        if($backBucketData){
            foreach ($backBucketData as $key=>$value){
                $warehouseSpaceProductData = (new WarehouseSpaceProduct())->getNormalWarehouseSpaceProductFind([['a.product_id','=',$value['product_id']],['a.isdel','=','0']],'b.warehouse_name,c.warehouse_space_name,a.warehouse_id,a.warehouse_space_id');
                $backBucketDatas[$key]['order_product_water_id'] = 0;
                $backBucketDatas[$key]['product_name'] = $value['product_name'];
                $backBucketDatas[$key]['sellcount'] = $value['tcount'];
                $backBucketDatas[$key]['selltypeenum'] = 1;
                $backBucketDatas[$key]['product_id'] = $value['product_id'];
                $backBucketDatas[$key]['warehouse_id'] = $warehouseSpaceProductData['warehouse_id'];
                $backBucketDatas[$key]['warehouse_space_id'] = $warehouseSpaceProductData['warehouse_space_id'];
                $backBucketDatas[$key]['warehouse_name'] =  $warehouseSpaceProductData['warehouse_name'];
                $backBucketDatas[$key]['warehouse_space_name'] =  $warehouseSpaceProductData['warehouse_space_name'];
            }
        }
        $waterData = array_merge($waterData,$productData,$backBucketDatas);
        $data = array(
            'collectionCode'=> $orderData['goods_code'],
            'waterData' => $waterData,
            'bucketData' => $bucketData,
        );
        return show(config("status.success"),"自提订单详情",$data);
    }

    /**
     * 自提出厂审核
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function sinceOut(){
        $order_id = $this->request->param('order_id');
        if(empty($order_id)){
            return show(config("status.error"),"缺少参数订单id");
        }
        //出售商品数据：product_id,count,warehouse_id,warehouse_space_id
        $outGoodsData = $this->request->param('outGoodsData');
        //回桶数据：product_id,count,warehouse_id,warehouse_space_id
        $inGoodsData = $this->request->param('inGoodsData');

        $orderData = (new Order())->getOrderFind([['order_id','=',$order_id]],'takestateenum,iscancel');
        if($orderData['iscancel'] == 1){
            return show(config("status.error"),"该笔订单已取消,不允许操作");
        }
        if($orderData['takestateenum'] == 1){
            return show(config("status.error"),"该笔订单请先去收银处理,再审核");
        }
        if($orderData['takestateenum'] == 4){
            return show(config("status.error"),"该笔订单已完成,不允许重复操作");
        }
        if(empty($outGoodsData)){
            $passWaterCount = (new OrderProductWater())->getOrderProductWaterSum([['order_id','=',$order_id]]);
            if($passWaterCount>0){
                return show(config("status.error"),"订单信息已改变，请重新刷新此页面");
            }
            $passProductCount = (new OrderProductNormal())->getOrderProductNormalSum([['order_id','=',$order_id]]);
            if($passProductCount>0){
                return show(config("status.error"),"订单信息已改变，请重新刷新此页面");
            }
        }else{
            foreach ($outGoodsData as $value) {
                if(empty($value['warehouse_id'])){
                    return show(config("status.error"),"出库商品缺少仓库id");
                }
                $productData = (new Product())->getProductFind([['product_id','=',$value['product_id']]],'product_name,tcount');
                if($productData['tcount']-$value['count']<0){
                    return show(config("status.error"),"该订单中【".$productData['product_name']."】库存不足，不允许提交");
                }
            }
        }
        if($inGoodsData){
            foreach ($inGoodsData as $value) {
                if(empty($value['warehouse_id'])){
                    return show(config("status.error"),"入库商品缺少仓库id");
                }
            }
        }
        try {
            Db::startTrans(); // 开始事务
            $orderSaveData['takestateenum'] = 4;
            $orderSaveData['completedate'] = date("Y-m-d H:i:s",time());
            $orderSaveData['sendokdate'] = date("Y-m-d H:i:s",time());
            $orderSaveData['outdate'] = date("Y-m-d H:i:s",time());
            $orderSaveData['backdate'] = date("Y-m-d H:i:s",time());
            $orderSaveData['worker_id_product_out'] = $this->workerId;
            $orderSaveData['worker_name_product_out'] = $this->workerName;
            $orderSaveRes = (new Order())->saveOrderData($order_id,$orderSaveData);
            if(empty($orderSaveRes)){
                return show(config("status.error"),"操作订单失败");
            }
            //添加出库单
            if($outGoodsData){
                $outAddData['company_id'] = $this->companyId;
                $outAddData['shop_id'] = $this->shopId;
                $outAddData['order_sn'] = (new Str())->makeOrderNo($this->shopId,7);
                $outAddData['worker_id'] = $this->workerId;
                $outAddData['worker_name'] = $this->workerName;
                $outAddData['adddate'] = date("Y-m-d H:i:s",time());
                $outAddData['note'] = "自提订单出库";
                $outAddData['outtypeenum'] = 32;
                $outAddData['modeltypeenum'] = 6;
                $outAddData['modelid'] = $order_id;
                $outRes = (new Out())->addOutData($outAddData);
                if($outRes){
                    $outProduct = [];
                    foreach ($outGoodsData as $key=>$value){
                        $productData = (new Product())->getProductFind([['product_id','=',$value['product_id']]],'typeenum,price_unit,tcount');
                        $outProduct[$key]['out_id'] = $outRes;
                        $outProduct[$key]['warehouse_id'] = $value['warehouse_id'];
                        $outProduct[$key]['warehouse_space_id'] = $value['warehouse_space_id'];
                        $outProduct[$key]['product_id'] = $value['product_id'];
                        $outProduct[$key]['tcount'] = $value['count'];
                        $outProduct[$key]['price_unit'] = $productData['price_unit'];
                        $outProduct[$key]['producttypeenum'] = $productData['typeenum'];
                        $outProduct[$key]['count_before'] = $productData['tcount'];
                        $outProduct[$key]['count_after'] = $productData['tcount']-$value['count'];
                        $outProduct[$key]['adddate'] = date("Y-m-d H:i:s",time());

                        $warehouseSpaceProductWhere = [
                            ['warehouse_id','=',$value['warehouse_id']],
                            ['warehouse_space_id','=',$value['warehouse_space_id']],
                            ['product_id','=',$value['product_id']],
                            ['isdel','=','0']
                        ];
                        (new WarehouseSpaceProduct())->saveDecWarehouseSpaceProductField($warehouseSpaceProductWhere,'tcount',$value['count']);

                        (new Product())->saveDecProductField([['product_id','=',$value['product_id']]],'tcount',$value['count']);
                    }
                    (new OutProduct())->addAllOutProduct($outProduct);
                }
            }
            //添加入库单
            if($inGoodsData){
                $inAddData['company_id'] = $this->companyId;
                $inAddData['shop_id'] = $this->shopId;
                $inAddData['order_sn'] = (new Str())->makeOrderNo($this->shopId,6);
                $inAddData['worker_id'] = $this->workerId;
                $inAddData['worker_name'] = $this->workerName;
                $inAddData['adddate'] = date("Y-m-d H:i:s",time());
                $inAddData['note'] = "自提订单入库";
                $inAddData['intypeenum'] = 32;
                $inAddData['modeltypeenum'] = 6;
                $inAddData['modelid'] = $order_id;
                $inRes = (new In())->addInData($inAddData);
                if($inRes){
                    $inProduct = [];
                    foreach ($inGoodsData as $key=>$value){
                        $productData = (new Product())->getProductFind([['product_id','=',$value['product_id']]],'typeenum,price_unit,tcount');
                        $inProduct[$key]['in_id'] = $inRes;
                        $inProduct[$key]['warehouse_id'] = $value['warehouse_id'];
                        $inProduct[$key]['warehouse_space_id'] = $value['warehouse_space_id'];
                        $inProduct[$key]['product_id'] = $value['product_id'];
                        $inProduct[$key]['tcount'] = $value['count'];
                        $inProduct[$key]['price_unit'] = $productData['price_unit'];
                        $inProduct[$key]['producttypeenum'] = $productData['typeenum'];
                        $inProduct[$key]['count_before'] = $productData['tcount'];
                        $inProduct[$key]['count_after'] = $productData['tcount']+$value['count'];
                        $inProduct[$key]['adddate'] = date("Y-m-d H:i:s",time());

                        $warehouseSpaceProductWhere = [
                            ['warehouse_id','=',$value['warehouse_id']],
                            ['warehouse_space_id','=',$value['warehouse_space_id']],
                            ['product_id','=',$value['product_id']],
                            ['isdel','=','0']
                        ];
                        (new WarehouseSpaceProduct())->saveInWarehouseSpaceProductField($warehouseSpaceProductWhere,'tcount',$value['count']);
                        (new Product())->saveInProductField([['product_id','=',$value['product_id']]],'tcount',$value['count']);
                    }
                    (new InProduct())->addAllInProduct($inProduct);
                }
            }
            // 提交事务
            Db::commit();
            return show(config("status.success"),"操作成功",['success'=>200]);
        }catch (\Exception $e){
            // 回滚事务
            Db::rollback();
            return show(config("status.error"),$e->getMessage());
        }
    }
}
